<script setup>
import {computed, ref, watchEffect} from "vue";
import {useSysDictById, useSysDictMutations} from "@/composables/sys/dict.js";
import {NButton, NFormItem, NIcon, NInput, NInputNumber, NSpace, useMessage} from "naive-ui";
import {CloseOutline, AddOutline} from '@vicons/ionicons5'

const emits = defineEmits(["close", "success"])
const formRef = ref(null)
const props = defineProps({
  show: {
    type: Boolean,
    required: false
  },
  id: {
    type: String,
    required: false
  }
})

// 编辑处理
const idRef = computed(() => props.id)
const {data, isLoading} = useSysDictById(idRef)

const isEdit = computed(() => !!props.id)

const message = useMessage()
const sysDictMutations = useSysDictMutations()

const createDefaultFormData = () => ({
  id: null,
  name: '',
  code: '',
  description: '',
  sort: 1,
  items: [{
    value: '',
    label: '',
    description: '',
    sort: 1
  }]
})

const formData = ref({...createDefaultFormData()})
const formRules = {
  name: [
    {required: true, message: '请输入字典名称', trigger: 'blur'}
  ],
  code: [
    {required: true, message: '请输入字典编码', trigger: 'blur'}
  ],
  sort: [
    {required: true, type: 'number', message: '请输入排序号', trigger: 'blur'}
  ],
  items: [
    {type: 'array', min: 1, message: '请至少添加一个字典项', trigger: 'blur'}
  ]
}

// 关闭
const close = () => {
  emits('close')
  formData.value = {...createDefaultFormData()}
}

// 提交
const formSubmit = () => {
  formRef.value?.validate(async (errors) => {
    if (!errors) {
      try {
        if (isEdit.value) {
          await sysDictMutations.update.mutateAsync(formData.value)
          message.success('修改成功')
        } else {
          await sysDictMutations.create.mutateAsync(formData.value)
          message.success('新增成功')
        }
        emits('success')
        close()
      } catch (e) {
        console.error(e)
      }
    }
  })
}

const itemsTableColumns = [
  {
    title: '字典项名称',
    key: 'label',
    width: 150,
    render(row, index) {
      return h(
          NFormItem,
          {
            path: `items[${index}].label`,
            rule: {required: true, message: '请输入字典项名称', trigger: 'blur'}
          },
          {
            default: () => h(
                NInput,
                {
                  size: 'small',
                  value: row.label,
                  placeholder: '字典项名称',
                  onUpdateValue: (val) => {
                    row.label = val
                  }
                }
            )
          }
      )
    }
  },
  {
    title: '字典项值',
    key: 'value',
    render(row, index) {
      return h(
          NFormItem,
          {
            path: `items[${index}].value`,
            rule: {required: true, message: '请输入字典项值', trigger: 'blur'}
          },
          {
            default: () => h(
                NInput,
                {
                  size: 'small',
                  value: row.value,
                  placeholder: '字典项值',
                  onUpdateValue: (val) => {
                    row.value = val
                  }
                }
            )
          }
      )
    }
  },
  {
    title: '排序号',
    key: 'sort',
    width: 120,
    render(row) {
      return h(
          NInputNumber,
          {
            type: 'number',
            value: row.sort,
            size: 'small',
            min: 1,
            max: 999,
            placeholder: '请输入排序号',
            onUpdateValue: (val) => {
              row.sort = val
            }
          }
      )
    }
  },
  {
    title: '描述',
    key: 'description',
    render(row) {
      return h(
          NInput,
          {
            size: 'small',
            value: row.description,
            placeholder: '请输入描述',
            onUpdateValue: (val) => {
              row.description = val
            }
          }
      )
    }
  },
  {
    title: '操作',
    key: 'actions',
    width: 100,
    render(row, index) {
      return h(
          NSpace,
          {},
          {
            default: () => [
              formData.value.items.length > 1 ? h(
                  NButton,
                  {
                    size: 'tiny',
                    type: 'error',
                    circle: true,
                    onClick: () => {
                      formData.value.items.splice(index, 1)
                      // 删除后触发验证
                      formRef.value?.validate()
                    }
                  },
                  {
                    icon: () => h(NIcon, null, {default: () => h(CloseOutline)})
                  }
              )  : null,
              h(
                  NButton,
                  {
                    size: 'tiny',
                    type: 'primary',
                    circle: true,
                    onClick: () => {
                      formData.value.items.push({
                        value: '',
                        label: '',
                        description: '',
                        sort: formData.value.items.length + 1
                      })
                      // 添加后触发验证
                      formRef.value?.validate()
                    }
                  },
                  {
                    icon: () => h(NIcon, null, {default: () => h(AddOutline)})
                  }
              )
            ]
          }
      )
    }
  }
]

// 监听编辑数据
watchEffect(() => {
  if (props.id && data?.value?.data && !isLoading.value) {
    formData.value = {
      ...data.value.data
    }
  }
})
</script>

<template>
  <n-drawer
      :show="show"
      :default-width="800"
      :min-width="600"
      resizable
      @esc="close"
  >
    <n-drawer-content>
      <template #header>
        {{ isEdit ? '编辑字典' : '新增字典' }}
      </template>
      <n-form ref="formRef" :model="formData" :rules="formRules">
        <n-form-item label="字典名称" path="name">
          <n-input v-model:value="formData.name" placeholder="请输入字典名称"/>
        </n-form-item>
        <n-form-item label="字典编码" path="code">
          <n-input
              v-model:value="formData.code"
              placeholder="请输入字典编码"
              :disabled="isEdit"
          />
        </n-form-item>
        <n-form-item label="排序号" path="sort">
          <n-input-number class="w-full" v-model:value="formData.sort" :min="1" :max="999" placeholder="请输入排序号"/>
        </n-form-item>
        <n-form-item label="字典描述" path="description">
          <n-input
              v-model:value="formData.description"
              placeholder="请输入字典描述"
              type="textarea"
          />
        </n-form-item>
        <n-form-item label="字典项" path="items">
          <n-data-table
              max-height="800"
              size="small"
              :columns="itemsTableColumns"
              :data="formData.items"
          />
        </n-form-item>
      </n-form>

      <template #footer>
        <n-space>
          <n-button size="small" @click="close">关闭</n-button>
          <n-button size="small" type="primary" @click="formSubmit">确定</n-button>
        </n-space>
      </template>
    </n-drawer-content>
  </n-drawer>
</template>

<style scoped>

</style>